import React, {Component} from 'react';
import { observable, action, autorun, computed } from 'mobx';
import {Tools, Bubble } from 'weaver-mobile';
import { SearchAdvanced, ListViewPage } from 'weaver-mobile-page';
import { RouteLayout, Reply, CKRichText } from 'weaver-mobile-page';
import showTemplates from '../../components/outSign/record/ListTemplate';
import subTemplates from '../../components/resource/showTemplates/index';
import * as api from '../../apis/sign';
import * as resourceAPI from '../../apis/resource';
import BaseStore from '../BaseStore';
import has from 'lodash/has';
import isEmpty from 'lodash/isEmpty';
import moment from 'moment';
import classnames from 'classnames';

const getLabel = Tools.getLabel;
const CKRichEditor = CKRichText.CKRichEditor;

const isIPhone = new RegExp('\\biPhone\\b|\\biPod\\b', 'i').test(window.navigator.userAgent);
let wrapProps;
if (isIPhone) {
  wrapProps = {
    onTouchStart: e => e.preventDefault(),
  };
}

const conditionUrl = '/api/hrm/kq/attendanceButton/getOutButtonCondition';
const subConditionUrl = '/api/public/browser/condition/1'

class OutSignStore extends BaseStore{
    deviceInfo;
    currentPage = 1; 
    pageSize = 20;
    dataTemp = {};
    otherParams = {};
    resourceId;
    selectedNearPosition = false;

    leftConfig = [
        { type: 'voice' },
        { type: 'blog-tupian'},
        // { type: 'tianjia'}
    ];

    recordRoute = '/outSign/';

    spinning = false;

    @observable baseInfo = {};
    @observable outButtonRange = {};

    @observable signLayout = new RouteLayout.Store({ route: '/outSign', id: 'sign' });
    @observable recordLayout = new RouteLayout.Store({ route: '/outSign', id: 'record' });
    @observable searchNearByLayout = new RouteLayout.Store({ route: '/outSign', id: 'searchNearBy' });
    @observable advanceSearchPageStore = new SearchAdvanced.Store({route: '/outSign', id: 'advanceSearch'});
    @observable advanceSearchPageStore1 = new SearchAdvanced.Store({route: '/outSign/record', id: 'advanceSearch'});
    @observable subAdvanceSearchPageStore = new SearchAdvanced.Store({route: '/outSign', id: 'subAdvanceSearch'});
    @observable replyStore = new Reply.Store({ getAttachList: () => (
        new Promise(resolve => {
            resolve(
                {
                    attachList: [
                        {
                          key: 'crm', // 字符串
                          type: 'browser',
                          path: '/outSign/sign/browser',
                          config: {
                            type: 7,
                            isSingle: false,
                            hasAdvanceSerach: true,
                          },
                          iconType: 'customer',
                          iconBgColor: '#E87E58',
                          text: getLabel('136','客户'),
                        },
                    ]
                }
            )
        })
    )});
    @observable ckStore = new CKRichEditor.Store({ initEndCallback: () => {
        const { editor } = this.ckStore;
        editor.on('focus', () => {
            this.hideReply();
        }); // onFocus时关闭reply组件
        // this.ckStore.focus('first'); // 获取焦点
    } });


    @observable initialPage = 0;
    @observable recordInitialPage = 0;
    @observable viewType = 0;//0.list 1.map
    
    @observable currentPositionData = {};
    @observable positionStatus = false;

    @observable showSchedual = false;

    @observable listViewStore = new ListViewPage.Store();
    @observable listDatas = [];
    @observable count = 0;

    @observable nearList = [];
    @observable selectedNearIndex = 0;

    @observable searchDate = this.moment().format('YYYY-MM-DD');

    @observable subordinates = {};
    @observable currTime = '';
    @observable _cTime = moment();

    @observable photo = '';
    @observable remark = '';
    @observable nearly = '';
    poitypes = '';

    @observable nearCurrentPage = 1;
    @observable nearListViewStore = new ListViewPage.Store();
    

    monitorTabPage = () => {
        this.initialPage;
        if(this.initialPage == 1){
            this.setActiveTab(0);
        }
	}

    @computed get cTime(){
        return this.toJS(this._cTime);
    }

    set cTime(v){
        this._cTime = v;
    }

    monitor = autorun(this.monitorTabPage);
    
    getConditionParams = () => {
        let s = (this.resourceId == null ? this.advanceSearchPageStore : this.advanceSearchPageStore1);
        const {form: {formParams}} = s;
        return formParams;
    }

    getQueryParams = () => {
        const params = {
            ...this.getConditionParams(),
            pageIndex: this.currentPage,
            pageSize: this.pageSize
        }
        this.resourceId != null && Object.assign(params, {resourceId: this.resourceId});
        return params;
    }

    clearParams = () => {
        this.selectedNearPosition = false;
        this.resourceId = null;
        this.currentPage = 1;
    }

    @action cleanMonitor = () => {
        if(this.timeMonitor != null){
            clearInterval(this.timeMonitor);
        }
    }

    get ua(){
        return Tools.ua;
    }

    @action getDeviceInfo = () => {
        let browserType = '';
        if(this.ua != null)
            browserType = this.ua.browser.toLowerCase();
        let func = 'getClientInfo';
        if(browserType == 'dingtalk')
            func = 'getNetWorkInfo';
        
        if(window.em && window.em.checkJsApi(func)){
            window.em.ready(() => {
                window.em[func]({
                    success: (res) => {
                        if(func == 'getNetWorkInfo'){
                            this.deviceInfo = {
                                SSID: res.ssid || res.SSID, //sid
                                BSSID: res.macIp || res.BSSID,//mac
                                networkType: res.networkType,
                                deviceId: res.deviceId
                            }
                        }else{
                            this.deviceInfo = res;
                        }
                    },
                    fail: (res) => {
                        if(browserType == 'emobile')
                            Bubble.error(getLabel('504566','无法获取设备信息'));
                        this.deviceInfo = {}
                    }
                });
            });
        }else{
            let msg = '';
            if(window.em == null){
                msg = 'em not found, ';
            }else if(!window.em.checkJsApi(func)){
                msg = `${func} not found, `;
            }
            if(browserType == 'emobile')
                Bubble.error(`${msg}${getLabel('504566','无法获取设备信息')}`);
            this.deviceInfo = {}
        }
    }

    @action init = () => {
        this.clearParams();
        this.Toast.loading('loading', 0);
        this.getDeviceInfo();
        api.initOutside().then(rs => {
            rs.map((result, index) => {
                if(result.status === '1' || result.status == null){
                    switch(index){
                        case 0:
                            this.baseInfo = result;
                            this.cTime = (result.timemillis != null ? moment(new Date(result.timemillis)) : moment());
                            this.cleanMonitor();
                            this.monitor = setInterval(() => {
                                this.cTime = this.cTime.add(1, 'seconds');
                            }, 1000);
                            if(this.baseInfo.hasCrmModule){
                                this.leftConfig.push({ type: 'tianjia'});
                            }
                            break;
                        case 1:
                            this.outButtonRange = result;
                            break;
                    }
                }
            });
            this.Toast.hide();
        }).catch(reason => this.Toast.hide());

        api.getOutSignSetting().then(res => {
            if(res.status == '1'){
                this.remark = res.remark;
                this.photo = res.photo;
                this.nearly = res.nearly;
                this.poitypes = res.poitypes;
            }
        })
        
        this.initMapPage();
    }

    /**
     * 外勤签到事件
     */
    @action callOutSign = (data, callback) => {
        if(this.spinning)
            return;
        this.spinning = true;
        const {imgList} = this.replyStore.getDatas();
        const {text: remark, currTime, currentPositionData: {address, longitude, latitude}} = data;
        // const {imgList, richText: remark} = this.ckRichTextStore.getData();
        // const {currentPositionData: {address, longitude, latitude}} = data;
        const fileids = imgList.map(d => d.fileid).join(',');
        if(this.remark == '1' && this.photo == '0' && remark.length <= 1){
                this.spinning = false;
                Bubble.warning(getLabel('514419','请填写备注!'))
        }
        else if(this.photo == '1' && this.remark == '0' && fileids.length <= 0){
                this.spinning = false;
                Bubble.warning(getLabel('512795','请上传照片!'))
        }
        else if(this.photo == '1' && this.remark == '1' && (fileids.length <= 0 || remark <= 1)){
                this.spinning = false;
                Bubble.warning(getLabel('514101','请上传照片和填写备注!'))
        }
        else{
            const {signSection, outsidesign} = this.outButtonRange;
            const params = {
                remark, 
                address,
                longitude,
                latitude,
                fileids,
                signSection,
                outsidesign,
                ...this.otherParams,
                deviceInfo: JSON.stringify(this.deviceInfo)
            }
            const ua = Tools.ua;
            has(ua, 'browser') && Object.assign(params, {browser: ua.browser});
            api.punchOutButton(params).then(data =>{
                if(data.status === '1'){
                    this.initialPage = 1;
                    let msg = getLabel('504568','外勤签到成功');
                    if(data.message != null && data.message.trim() != '')
                        msg += `,${data.message}`;
                    Bubble.success(msg);
                    callback && callback();
                }else{
                    Bubble.error(data.message);
                }
                this.spinning = false;
            }, error => {
                Bubble.error(error.message);
                this.spinning = false;
            })
        }
       
    }

    @action setShowSchedual = () => {
        this.showSchedual = !this.showSchedual;
    }

    @action initMapPage = () => {
        if(window.em && window.em.checkJsApi('getLocation')){
            if(window.em && window.em.checkJsApi('dingAuthFunc')){
                window.em.dingAuthFunc();
            }
            window.em.ready(() => {
                window.em.getLocation({
                    type: 'gcj02',
                    success: (res) => {
                        this.currentPositionData = {address: '', ...res};
                        isEmpty(this.currentPositionData.address) && this.regeo();
                        this.positionStatus = true;
                    },
                    onLocationChanged:(res) => {
                        if(this.selectedNearPosition)
                            return;
                        if(typeof(res) === 'string')
                            res = JSON.parse(res);
                        this.currentPositionData = {address: '', ...res};
                        isEmpty(this.currentPositionData.address) && this.regeo();
                        this.positionStatus = true;
                    },
                    fail: (res) => {
                        this.positionStatus = false;
                        Bubble.error(<div onClick={() => Bubble.error(res.errMsg)}>{getLabel('504565','无法获取定位信息')}</div>);
                    }
                });
            });
        }else{
            let msg = '';
            if(window.em == null){
                msg = 'em not found, ';
            }else if(!window.em.checkJsApi('getLocation')){
                msg = 'getLocation not found, ';
            }
            Bubble.error(`${msg}${getLabel('504565','无法获取定位信息')}`);
            // test
            // setTimeout(() => {
            //     this.currentPositionData = {
            //         address: '',
            //         longitude: 121.52646,
            //         latitude: 31.08013
            //     }
            //     this.positionStatus = true;
            //     this.regeo()
            // }, 1000);
        }
    }

    @action setTabPage = v => this.initialPage = v;

    @action setActiveTab = index => {
        this.recordInitialPage = index;
        if(index == 0){
            this.viewType = 0;
            this.querySearchCondition();
        }
    }

    @action setViewType = v => this.viewType = v;

    @action cleanData = () => {
        this.currentPage = 1;
        this.listDatas.length = 0;
        this.dataTemp = {};
    }

    @action refreshData = (resourceId) => {
        this.resourceId = resourceId;
        this.listDatas.length = 0;
        this.dataTemp = {};
        this.setCurrentPage(1);
    }

    @action setCurrentPage = idx => {
        if(idx == null)
            this.currentPage++;
        else if(idx === this.currentPage && this.currentPage != 1){
            this.listViewStore.setState({hasMore: false, loading: false});
            return;
        } else{
            this.cleanData();
        }
        this.queryData(this.getQueryParams());
    }

    @action querySearchCondition = (resourceId) => {
        let s = (resourceId == null ? this.advanceSearchPageStore : this.advanceSearchPageStore1);
        s.getData({
            url: conditionUrl
        }).then(form => {
            this.doReset(resourceId);
            this.cleanData();
            this.refreshData(resourceId);
        });
    }

    @action doReset = (resourceId) => {
        let s = (resourceId == null ? this.advanceSearchPageStore : this.advanceSearchPageStore1);
        const {
            form
        } = s;
        form.resetFields();
    }

    @action queryData = (params) => {
        this.listViewStore.setState({
            loading: true
        });
        api.getOutSearchList({data: JSON.stringify({...params, order: 1})}).then(data => {
            if(data.status == '1')
                this.setListData(data);
        }, error => {});
    }

    @action doSearch = () => this.refreshData(this.resourceId);

    @action setListData = data => {
        const { count } = data;
        const datas = data.datas.map((d, index) => {
            return {
                ...d,
                imgList: d.attachment.map(v => `/weaver/weaver.file.FileDownload?fileid=${v}`)
            }
        });
        const { template } = showTemplates;
        this.count = count;
        this.listDatas = [...this.toJS(this.listDatas), ...datas];
        
        const dataSource = this.listViewStore.dataSource.cloneWithRows(this.toJS(this.listDatas));
        this.listViewStore.setState({
            nameKey: this.nameKey,
            rowKey: this.rowKey,
            data: this.listDatas,
            template: { template },
            dataSource,
            hasMore: datas.length > 0 && this.count >= this.pageSize,
            loading: false,
            isTable: false,
            getData: () => {}
        });
    }

    @action querySubordinates = (resource) => {
        this.subordinates = resource;
        this.viewType= 0;
        this.querySearchCondition(resource.id);
    }

    @action setSelectedNearIndex = (index, callback) => {
        const clz = (c) => classnames({
            selected: true,
            selected_hide: c !== index 
        })
        document.getElementById(this.selectedNearIndex).setAttribute('class',clz(this.selectedNearIndex));
        document.getElementById(index).setAttribute('class',clz(index));

        this.selectedNearIndex = index;
        callback && callback(this.getSelectedLocation());
    }

    formatUrl = params => {
        params = Object.values(params).reduce((a,b,i) => `${a}${Object.keys(params)[i]}=${b}&`, '?');
        return params.substring(0, params.length - 1);
    }

    @action searchNearBy = (callback, currentPage) => {
        if(!this.positionStatus)
            return;
        if(callback){
            this.selectedNearIndex = 0
        }
        // this.nearList.length = 0;
        // this.selectedNearIndex = 0;

        this.nearListViewStore.setState({
            loading: true
        });

        fetch(`https://restapi.amap.com/v3/place/around${this.formatUrl({
            key: window.gaodeMapWebKey,
            location: `${this.currentPositionData.longitude},${this.currentPositionData.latitude}`,
            radius: 1000,
            types: this.poitypes,
            page: currentPage || this.nearCurrentPage,
            offset: 100,
            extensions:'all'
        })}`, {method: 'GET'}).
        then(res => res.json())
        .catch(err => Bubble.error(JSON.stringify(err)))
        .then(data => {
            if(data.status == '1'){
                const listData = data.pois.map((p, idx) => {
                    const [longitude, latitude] = p.location.split(',');
                    return {
                        id: ((currentPage || 1) - 1) * 50 + idx,
                        name: p.name,
                        address: p.address,
                        longitude,
                        latitude
                    }
                })
                this.nearList = [...this.toJS(this.nearList),...listData]
                const dataSource = this.nearListViewStore.dataSource.cloneWithRows(this.toJS(this.nearList));
                this.nearListViewStore.setState({
                    nameKey: this.nameKey,
                    rowKey: this.selectedNearIndex,
                    data: this.nearList,
                    pageSize: 50,
                    dataSource,
                    hasMore: listData.length > 0,
                    loading: false,
                    isTable: false,
                    getData: () => {}
                });
                callback && callback();
            }else{
                Bubble.error('Request https://restapi.amap.com/v3/place/around failed.');
            }
        });
    }

    @action regeo = () => {
        if(this.currentPositionData.longitude != null && (this.currentPositionData.address == null || this.currentPositionData.address == '')){
            fetch(`https://restapi.amap.com/v3/geocode/regeo${this.formatUrl({
                key: window.gaodeMapWebKey,
                location: `${this.currentPositionData.longitude},${this.currentPositionData.latitude}`,
                radius: 1000,
                poitype: '',
                extensions: 'all',
                batch: 'false',
                roadlevel: '0'
            })}`, {method: 'GET'}).
            then(res => res.json())
            .catch(err => {
                Bubble.error('call amap regeo failed');
                // this.positionStatus = false;
            })
            .then(data => {
                if(data.status == '1'){
                    this.currentPositionData.address = '';
                    let {formatted_address: address} = data.regeocode;
                    this.currentPositionData.address = address || '';
                    // this.positionStatus = true;
                }else{
                    Bubble.error(JSON.stringify(data));
                    // this.positionStatus = false;
                }
            });
        }
    }

    @action getSelectedLocation = () => {
        return this.toJS(this.nearList)[this.selectedNearIndex];;
    }

    @action changeLocation = callback => {
        this.selectedNearPosition = true;
        const location = this.toJS(this.currentPositionData);
        Object.assign(location, this.getSelectedLocation());
        this.currentPositionData = location;
        callback && callback();
    }

    @action setSearchDate = (date, callback) => {
        this.searchDate = date;
        this.queryMapData(callback);
    }

    @action queryMapData = (callback) => {
        let params = this.getQueryParams();
        delete params.pageIndex;
        delete params.pageSize;
        const d = this.moment(this.toJS(this.searchDate)).format('YYYY-MM-DD');
        params = {...params, typeselectselect: '6', typeselectfrom: d, typeselectto: d};

        api.getOutSearchList({data: JSON.stringify(params)}).then(data => {
            if(data.status == '1'){
                if(data.datas.length == 0){
                    Bubble.warning(getLabel(83553, '暂无数据'));
                }
                callback && callback(data.datas);
            }
        }, error => {});
    }

    @observable subCurrentPage = 1;
    @observable subListDatas = [];
    @observable subCount = 0;
    @observable showPop = false;
    @observable alllevel = true;
    @observable subListViewStore = new ListViewPage.Store();
    queryResourceId;

    getSubConditionParams = () => {
        const {form: {formParams}} = this.subAdvanceSearchPageStore;
        return formParams;
    }

    getSubQueryParams = () => {
        let params = {
            cmd: 'search',
            mobileResourceId: this.queryResourceId,
            ...this.getSubConditionParams()
        };
        params.min = (this.subCurrentPage - 1) * this.pageSize + 1;
        params.max = this.subCurrentPage * this.pageSize;
        if (this.alllevel) {
            params.alllevel = 1;
        }
        return params;
    }

    @action initSubordinatePage = (resourceId) => {
        this.queryResourceId = resourceId;
        this.alllevel = true;
        this.querySubSearchCondition();
    }

    @action setShowPop = bool => this.showPop = bool;

    @action onPopoverSelectHandle = node => {
        this.alllevel = !this.alllevel;
        this.setSubCurrentPage(1);
        this.showPop = false;
    }

    @action querySubSearchCondition = () => {
        this.subAdvanceSearchPageStore.getData({
            url: subConditionUrl
        }).then(form => {
            this.doSubReset();
            this.cleanSubData();
            this.querySubData(this.getSubQueryParams());
        });
    }

    @action cleanSubData = () => {
        this.showPop = false;
        this.subCurrentPage = 1;
        this.subListDatas.length = 0;
    }

    @action refreshSubData = () => {
        this.subListDatas.length = 0;
        this.setSubCurrentPage(1);
    }

    @action setSubCurrentPage = idx => {
        if(idx == null)
            this.subCurrentPage++;
        else if(idx === this.subCurrentPage && this.subCurrentPage != 1){
            this.subListViewStore.setState({hasMore: false, loading: false});
            return;
        } else{
            this.cleanSubData();
        }
        this.querySubData(this.getSubQueryParams());
    }

    @action doSubReset = () => {
        const {
            form
        } = this.subAdvanceSearchPageStore;
        form.resetFields();
    }

    @action querySubData = (params) => {
        this.subListViewStore.setState({
            loading: true
        });
        resourceAPI.queryData(params).then(data => {
            const {
                datas
            } = data;
            if (Array.isArray(datas)) {
                this.setSubListData(data);
            }
        }, error => {});
    }

    @action setSubListData = data => {
        const {
            count,
            datas
        } = data;
        const {
            template
        } = subTemplates;
        this.subCount = count;
        this.subListDatas = [...this.toJS(this.subListDatas), ...datas];

        const dataSource = this.subListViewStore.dataSource.cloneWithRows(this.toJS(this.subListDatas));
        this.subListViewStore.setState({
            nameKey: this.nameKey,
            rowKey: this.rowKey,
            data: this.subListDatas,
            template: {
                template
            },
            dataSource,
            hasMore: datas.length > 0 && this.subCount >= this.pageSize,
            loading: false,
            isTable: false,
            getData: () => {}
        });
    }

    @action doQuickSearch = () => {
        this.cleanSubData();
        this.querySubData(this.getSubQueryParams());
    }

    @action onQuickSearchChangeHandle = v => {
        const {
            form
        } = this.subAdvanceSearchPageStore;
        form.updateField('lastname', v.toString());
    }

    @action onClearSearchCondition = () => {
        this.onQuickSearchChangeHandle('');
        this.doQuickSearch();
    }

    @action setSignDateTime = v => {
        this.currTime = v;
    }

    @action clearReplyData = () => {
        this.otherParams = {};
    }

    @action setOtherParams = (k, v) => {
        if(k == 'crm'){
            let ids = v.reduce((arr, d) => {
                arr.push(d.id);
                return arr;
            }, []).join(',');
            this.otherParams[k] = ids;
        }
    }


    @action refreshNearData = () => {
        this.setNearCurrentPage(1);
    }

    @action setNearCurrentPage = (idx) => {
        if(idx == null)
            this.nearCurrentPage++;
        else if(idx === this.nearCurrentPage && this.nearCurrentPage != 1){
            this.nearListViewStore.setState({hasMore: false, loading: false});
            return;
        } else{
            this.cleanNearData();
        }
        this.searchNearBy(null,this.nearCurrentPage);
    }

    @action cleanNearData = () => {
        this.nearCurrentPage = 1;
        this.selectedNearIndex = 0;
        this.nearList.length = 0;
    }

    hideReply = () => {
        this.replyStore.setState({ activeKey: '' });
    }

    onSpeechChange = datas => {
        this.insertHtml(`<span>${datas}</span>`);
    }

    insertHtml = (...args) => {
        this.ckStore.insertHtml(...args);
    }
}

export const outSignStore = new OutSignStore(); 